﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using T19.Baseclass;
using System.Runtime.InteropServices;

namespace T19
{
    public partial class FrmBlock : Form
    {
        private Bitmap bmBackground;
        private Bitmap bmPaddle;
        private static readonly Rectangle GamePaddleRect = new Rectangle(39, 1, 93, 23);
        private Point centerOfPaddle;
        private Bitmap bmBlock;
        private static readonly Rectangle GameBlockRect = new Rectangle(139, 1, 62, 27);
        private Block[,] blocks = new Block[12, 14];
        private int gamelevel = 1;
        private Bitmap bmBall;
        private static readonly Rectangle GameBallRect = new Rectangle(1, 1, 36, 36);
        private Rectangle paddleRect;
        [DllImport("winmm")]
        public static extern bool PlaySound(string szSound, int hMode, int i);
        private int gameLives = 4;
        private bool isGameOver = false;
        private bool bSounding = false;
  
        public FrmBlock()
        {
            InitializeComponent();
        }
        private void FrmBlock_Load(object sender, EventArgs e)
        {
            this.LoadPictures();
            centerOfPaddle.X = this.ClientRectangle.Width / 2;
            centerOfPaddle.Y = this.ClientRectangle.Height - 30;
            this.RandomBlockMap();
            Ball.BallRect = new Rectangle(centerOfPaddle.X - 36 / 2, centerOfPaddle.Y - 32, 36, 36);
            Ball.BallDirection = new Vector2(1.0f, -1.0f);
            paddleRect = new Rectangle(this.ClientRectangle.Width / 2 - 48, this.ClientRectangle.Height - 33, 96, 26);
            this.TimerRefreshScreen.Start();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            Bitmap bufferBm = new Bitmap(this.ClientRectangle.Width - 1,
                 this.ClientRectangle.Height - 1);
            Graphics g = Graphics.FromImage(bufferBm);
            this.DrawGame(g);
            e.Graphics.DrawImage(bufferBm, 0, 0);
            g.Dispose();
            base.OnPaint(e);
        }
        private void LoadPictures()
        {
            bmBackground = BitmapHelper.LoadBm("Background");
            Bitmap bmbreak = BitmapHelper.LoadBm("Break");
            bmPaddle = bmbreak.Clone(GamePaddleRect, bmbreak.PixelFormat);
            bmBlock = bmbreak.Clone(GameBlockRect, bmbreak.PixelFormat);
            bmBall = bmbreak.Clone(GameBallRect, bmbreak.PixelFormat);
        }
        private void DrawGame(Graphics g)
        {
            g.DrawImage(bmBackground,
                new Rectangle(0, 0,
                this.ClientRectangle.Width - 1,
                 this.ClientRectangle.Height - 1)
                 );
            g.DrawImage(bmPaddle,
                new Rectangle(centerOfPaddle.X - 93 / 2, centerOfPaddle.Y, 93, 23));
            for (int row = 0; row < 12; row++)
            {
                for (int col = 0; col < 14; col++)
                {
                    if (blocks[row, col].IsBlock)
                    {
                        g.DrawImage(bmBlock, blocks[row, col].BlockRect);

                    }
                }
            }
            // g.DrawImage(bmBall, new Rectangle(centerOfPaddle.X - 36 / 2, centerOfPaddle.Y - 36, 36, 36));
            g.DrawImage(bmBall, Ball.BallRect);
            g.DrawString("关卡：" + gamelevel.ToString(),
                new Font("仿宋", 24),
                new SolidBrush(Color.White),
                new Point(5, 5));
            g.DrawString("生命:"+(gameLives+1).ToString(),
                 new Font("仿宋", 24),
                  new SolidBrush(Color.White),
                  new Point(700, 5));
            if(isGameOver)
            {
                g.DrawString("游戏结束！",
                    new Font("仿宋", 48),
                     new SolidBrush(Color.White),
                     new Point(240, 280));
            }
        }
        private void FrmBlock_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.X <= 93 / 2)
            {
                centerOfPaddle.X = 93 / 2;
            }
            else if (e.X >= this.ClientRectangle.Width - 93 / 2)
            {
                centerOfPaddle.X = this.ClientRectangle.Width - 93 / 2;
            }
            else
            {
                centerOfPaddle.X = e.X;
            }
            paddleRect.X = centerOfPaddle.X - 48;
            // this.Invalidate();

        }
        private void RandomBlockMap()
        {
            for (int row = 0; row < 12; row++)
            {
                for (int col = 0; col < 14; col++)
                {
                    blocks[row, col] = new Block();
                    if (RandomHelper.GetRandomInt() < gamelevel)
                    {
                        blocks[row, col].IsBlock = true;
                        blocks[row, col].BlockRect = new Rectangle(62 * col, row * 27 + 60, 62, 27);
                    }


                }
            }
        }
        private void TimerRefreshScreen_Tick(object sender, EventArgs e)
        {

            Ball.BallRect.X += (int)(Ball.BallDirection.X * 8.0f);
            Ball.BallRect.Y += (int)(Ball.BallDirection.Y * 6.0f);
            //if (IsHit())
            //  play("Hit");
            //if (IsKill())
            // play("Kill");
            if (IsHit() && !bSounding)
            {
                play("Hit");
                bSounding = true;
                this.TimerAfterSound.Start();
            }
            if (IsKill() && !bSounding)
            {
                play("Kill");
                bSounding = true;
                this.TimerAfterSound.Start();
            }
            if (IsLost())
            play("Lost");
            if (Isvictory())
            {
                play("Victory");
                this.TimerRefreshScreen.Stop();
                this.Timerwait.Start();
                
            }
            this.IsGameOver();
            if(isGameOver)
            {
                this.TimerRefreshScreen.Stop();
            }
            this.Invalidate();

        }
        private void Timerwait_Tick(object sender, EventArgs e)
        {
            this.Timerwait.Stop();
            RandomBlockMap();
            Ball.BallRect.X = this.ClientRectangle.Width / 2 - 18;
            Ball.BallRect.Y = this.ClientRectangle.Height - RandomHelper.GetRandomInt(35, 60);
            Ball.BallDirection = new Vector2(1.0f, -1.0f);
            this.TimerRefreshScreen.Start();
        }
        private void TimerAfterSound_Tick(object sender, EventArgs e)
        {
            bSounding = false;
            this.TimerAfterSound.Stop();
        }
        private bool IsHit()
        {
            if (Ball.BallRect.X <= 3)
            {
                Ball.BallDirection.X = -Ball.BallDirection.X;
                return true;
            }
            if (Ball.BallRect.X >= this.ClientRectangle.Width - 39)
            {
                Ball.BallDirection.X = -Ball.BallDirection.X;
                return true;
            }
            if (Ball.BallRect.Y <= 3)
            {
                Ball.BallDirection.Y = -Ball.BallDirection.Y;
                return true;
            }
            if (Ball.BallRect.IntersectsWith(paddleRect))
            {
                Ball.BallDirection.Y = -Ball.BallDirection.Y;
                return true;
            }
            return false;

        }
        private bool IsKill()
        {
            for (int row = 0; row < 12; row++)
            {
                for (int col = 0; col < 14; col++)
                {
                    if (blocks[row, col].IsBlock && blocks[row, col].BlockRect.IntersectsWith(Ball.BallRect))
                    {
                        if (Math.Abs(blocks[row, col].BlockRect.X - Ball.BallRect.X) < 6 || Math.Abs(blocks[row, col].BlockRect.X - Ball.BallRect.X + 93 - 36) < 6)
                        {
                            Ball.BallDirection.X = -Ball.BallDirection.X;
                        }
                        else
                        {
                            Ball.BallDirection.Y = -Ball.BallDirection.Y;
                        }
                        blocks[row, col].IsBlock = false;
                        return true;
                    }
                }
            }
            return false;
        }
        private void play(string waveName)
        {
            PlaySound(Application.StartupPath + "\\GameSounds\\" + waveName + ".wav", 0, 1);
        }
        private bool IsLost()
        {
            if (Ball.BallRect.Y > this.ClientRectangle.Height - 18)
            {
                Ball.BallRect.Y = this.ClientRectangle.Height - RandomHelper.GetRandomInt(35, 60);
                Ball.BallDirection = new Vector2(1.0f, -1.0f);
                gameLives--;
                return true;
            }
            return false;
        }
        private bool Isvictory()
        {
            for (int row = 0; row < 12; row++)
            {
                for (int col = 0; col < 14; col++)
                {
                    if (blocks[row, col].IsBlock)
                        return false;
                }
            }
                return true;
         }
        private void IsGameOver()
        {
            if (gameLives < 0)
            isGameOver = true;
        }
    }
}